<?php

class dbController implements iDbController {
	
	private $enableCache = false,
	        $cache       = array (),
			$lifetime    = 0,
			$status      = false;
	private static $instance = false;
	
	/**
	 * Возвращает объект класса dbController
	 */
	public static function getInstance () {
		if (self::$instance === false) {
			self::$instance = new mysqlCacheController;
		}
		return self::$instance;
	}
	
	private function __construct () {
		if (!$this->status) {
			$this->connect ();
		}		
		$regedit = regedit::getInstance ();
		loadLang (DOC_ROOT . '/classes/dbController/i18n.php', 'db');
		$this->lifetime = $regedit->get ('//settings/cache/mysql_lifetime');
		$this->enableCache = ($regedit->get ('//settings/cache/mysql_enable_cache') == 1) ? true : false;
	}
	
	/**
	 * Аналог функции mysql_query, но при включенном кешировании возвращает стороку с ключем
	 */
	public function query ($sQuery, $lifetime = false) {
		if ($this->enableCache && eregi("^SELECT", $sQuery)) {
			return $this->queryWithCache ($sQuery, $lifetime);
		} else {
			return $this->queryWithoutCache ($sQuery);
		}
	}
	
	/**
	 * Аналог функции mysql_fetch_row
	 */
	public function fetch_row ($resourse) {
		if ($this->enableCache && !is_resourse ($resourse)) {
			return $this->returnCacheFetchRow ($resourse);
		} else {
			return mysql_fetch_row ($resourse);
		}
	}
	
	/**
	 * Аналог функции mysql_fetch_array
	 */
	public function fetch_array ($resourse) {
		if ($this->enableCache && !is_resourse ($resourse)) {
			return $this->returnCacheFetchArray ($resourse);
		} else {
			return mysql_fetch_array ($resourse);
		}
	}
	
	/**
	 * Аналог функции mysql_query
	 */
	public function queryWithoutCache ($sQuery) {
		$res = mysql_query ($sQuery);
			
		if (strlen (mysql_error ())) {
			throw new coreException (lang('error_mysql_query','db') . '<p />' . mysql_error ());
		}
		return $res;
	}
	
	/**
	 * Аналог функции mysql_num_rows
	 */
	public function num_rows ($resourse) {
		if ($this->enableCache && !is_resourse ($resourse)) {
			if (!isset ($this->cache[$key])) {
				throw new coreException (lang ('error_db_called_resourse_not_exists','db'));
			}
			return $this->cache[$key]['num_rows'];
		} else {
			mysql_num_rows ($resourse);
		}
	}
	
	/**
	 * Аналог функции mysql_data_seek
	 */
	public function reset_pointer ($resourse) {
		if ($this->enableCache && !is_resourse ($resourse)) {
			if (!isset ($this->cache[$key])) {
				throw new coreException (lang ('error_db_called_resourse_not_exists','db'));
			}
		} else {
			mysql_data_seek ($resourse, 0);
		}		
	}
	
	/**
	 * Очищает текущий кеш запроса (из переменной класса)
	 */
	public function clearCache ($key) {
		if (!isset ($this->cache[$key])) {
			throw new coreException (lang ('error_db_called_resourse_not_exists','db'));
		}

		unset ($this->cache[$key]);
	}
	
	/**
	 * Запрос с кешированием
	 */
	private function queryWithCache ($sQuery, $lifetime = false) {
		$key = md5 ($sQuery);
		$cacheController = cacheController::getInstance ();
		
		$cacheParams = array (
						'key'      => $key,
						'lifetime' => $lifetime !== false ? $lifetime : $this->lifetime,
						'dir'      => 'mysql'
					);
		if ($res = $cacheController ->getArray ($cacheParams)) { // Проверяем кеш
			if (!isset ($res['fields']) || !isset ($res['values'])) {
				throw new coreException (lang('error_db_empty_param','db') /*Кеш вернул неправильные данные*/);
			}
		} else { // Новый запрос
			$get = $this->queryWithoutCache ($sQuery);
			$res = array (
						'pos'      => 1,
						'num_rows' => 0,
						'fields'   => array (),
						'values'   => array ()
					);
			// Собираем информацию о полях
			$cntFields = mysql_num_fields ($get);
			for ($i=0; $i<$cntFields; ++$i) {
				$res['fields'][$i] = mysql_fetch_field ($get, $i);
			}
			// Записываем массивы значений
			$numRows = mysql_num_rows ($get);
			for ($i=0; $i<$numRows; ++$i) {
				$res['values'][$i] = mysql_fetch_row ($get);
			}
			$res['num_rows'] = $numRows;
			$cacheParams['value'] = $res;
			$cacheController ->writeArray ($cacheParams);
		}
		$this->cahce[$key] = $res;
		return $key;
	}
	
	/**
	 * Аналог функции mysql_fetch_row
	 */
	private function returnCacheFetchRow ($resourse) {
		if (!isset ($this->cache[$key])) {
			throw new coreException (lang ('error_db_called_resourse_not_exists','db'));
		}
		// Счетчик
		if (($this->cache[$key]['pos']+1) > $this->cache[$key]['num_rows']) {
			return false;
		}
		$this->cache[$key]['pos']++;
		return $this->cache[$key]['values'][$pos];
	}
	
	/**
	 * Аналог функции mysql_fetch_array
	 */
	private function returnCacheFetchArray ($resourse) {
		if (!isset ($this->cache[$key])) {
			throw new coreException (lang ('error_db_called_resourse_not_exists','db'));
		}
		// Счетчик
		if (($this->cache[$key]['pos']+1) > $this->cache[$key]['num_rows']) {
			return false;
		}
		$this->cache[$key]['pos']++;
		
		$res = $this->cache[$key];
		$cnt = count ($res['fields']);
		$response = array ();
		for ($i=0; $i<$cnt; ++$i) {
			$response[$res['fields'][$i]->name] = $res['values'][$i];
		}
		return $response;
	}
	
	private function connect () {
		// TODO
	}
}